package P108_ReflexWithTemplateMethodpattern;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * 反射让模板方法模式更强大
 *
 */
public class ReflexWithTemplateMethodPattern {

    public abstract class AbsPopulator {
        //模板方法
        public final void dataInitialing() {
            //调用基本方法
            doInit();
        }

        //基本方法
        protected abstract void doInit();
    }

    public class UserPopulator extends AbsPopulator {

        @Override
        protected void doInit() {
            //初始化用户表,如创建加载数据等
        }

    }

    public abstract class AbsPopulatorUp {
        //模板方法
        public final void dataInitialing() throws InvocationTargetException, IllegalAccessException {
            //获得所有的public方法
            Method[] methods = getClass().getMethods();
            for (Method method : methods) {
                //判断是不是数据初始化方法
                if (isInitDataMethod(method)) {
                    method.invoke(this);
                }
            }
        }

        private Boolean isInitDataMethod(Method method) {
            return method.getName().startsWith("init")           //方法名以init开头
                    && Modifier.isPublic(method.getModifiers())  //是不是public方法
                    && method.getReturnType().equals(Void.TYPE)  //有无返回值
                    && !method.isVarArgs()                       //有无入参
                    && !Modifier.isAbstract(method.getModifiers()); //是不是抽象方法

        }
    }
}
